import os
import asyncio
import aiohttp

async def fetch(session, url):
    try:
        async with session.get(url) as response:
            try:
                content = await response.text(errors='ignore')
            except UnicodeDecodeError:
                content = ""
            return content, response.status
    except aiohttp.ClientError as e:
        return None, None

async def scan_paths(base_url, wordlist):
    valid_paths = []
    other_status_codes = {}
    async with aiohttp.ClientSession() as session:
        tasks = []
        print("Scanning...")
        for path in wordlist:
            url = f"{base_url}/{path}"
            tasks.append(fetch(session, url))

        results = await asyncio.gather(*tasks)
        print("Scanning completed.")

        for i, (result, status_code) in enumerate(results):
            url = f"{base_url}/{wordlist[i]}"
            if status_code is None:
                print(f"Request failed: {url}")
                continue
            print(f"Scanning: {url} - Status code: {status_code}")
            if status_code == 200:
                valid_paths.append(url)
            elif status_code != 404:
                if status_code in other_status_codes:
                    other_status_codes[status_code].append(url)
                else:
                    other_status_codes[status_code] = [url]
    return valid_paths, other_status_codes

async def download_default_wordlist(url, save_path):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            if response.status == 200:
                content = await response.text()
                os.makedirs(os.path.dirname(save_path), exist_ok=True)
                with open(save_path, 'w') as file:
                    file.write(content)
                print(f"Download completed: {save_path}")
                return True
            else:
                print(f"Download failed, status code: {response.status}")
                return False

def find_default_wordlist(start_dir):
    for root, dirs, files in os.walk(start_dir):
        if 'default_subdomains.txt' in files:
            return os.path.join(root, 'default_subdomains.txt')
    return None

async def main():
    print("Select wordlist option:")
    print("[1] Default wordlist")
    print("[2] Custom wordlist")
    choice = input("Enter your choice (1 or 2): ")

    wordlist_file = None
    if choice == '1':
        wordlist_file = find_default_wordlist('.')
        if wordlist_file is None:
            print("Default wordlist file not found. Select wordlist to download:")
            print("[1] default_subdomains.txt (9.5k)")
            print("[2] default_subdomains300M.txt (300M) Not recommended")
            download_choice = input("Enter your choice (1 or 2): ")

            if download_choice == '1':
                download_url = 'https://example.com/path/to/default_subdomains.txt'  # Replace with actual URL
            elif download_choice == '2':
                print("Not recommended to download default_subdomains300M.txt (300M)")
                download_url = 'https://example.com/path/to/default_subdomains300M.txt'  # Replace with actual URL
            else:
                print("Invalid choice.")
                return

            save_path = 'Network_scanning/default_subdomains.txt'
            download_success = await download_default_wordlist(download_url, save_path)
            if download_success:
                wordlist_file = save_path
            else:
                print("Download failed, unable to continue.")
                return
    elif choice == '2':
        wordlist_file = input("Enter the custom wordlist file path: ")
    else:
        print("Invalid choice.")
        return

    base_url = input("Enter the base URL to scan (e.g., http://example.com): ")
    if not base_url.startswith('http://') and not base_url.startswith('https://'):
        print("Invalid URL.")
        return

    try:
        with open(wordlist_file, 'r') as file:
            wordlist = [line.strip() for line in file.readlines()]
    except FileNotFoundError:
        print(f"Wordlist file {wordlist_file} not found.")
        return

    if not wordlist:
        print("Failed to load wordlist.")
        return

    valid_paths, other_status_codes = await scan_paths(base_url, wordlist)

    print("\nHere are all the valid paths with status code 200:")
    for path in valid_paths:
        print(path)

    print("\nHere are the statistics of other status codes (excluding 404):")
    for status_code, urls in other_status_codes.items():
        print(f"Status code {status_code}:")
        for url in urls:
            print(f"  {url}")

if __name__ == "__main__":
    asyncio.run(main())

# pip install aiohttp
# sansjtw